package com.xw.qxypt.modules.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xw.qxypt.modules.dao.LhpInstallationPointDao;
import com.xw.qxypt.modules.entity.*;
import com.xw.qxypt.modules.service.*;
import com.xw.qxypt.modules.util.BaseTree;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;


@Service("lhpInstallationPointService")
public class LhpInstallationPointServiceImpl extends ServiceImpl<LhpInstallationPointDao, LhpInstallationPointEntity> implements LhpInstallationPointService {
    @Autowired
    private LhpEquipmentService lhpEquipmentService;
    @Autowired
    private LhpThresholdSettingService lhpThresholdSettingService;
    @Autowired
    private LhpAlertService lhpAlertService;
    @Autowired
    private LhpAlertHistoryService lhpAlertHistoryService;
    @Autowired
    private LhpDataVisibilityService lhpDataVisibilityService;
    @Autowired
    private LhpDataVisibilityHistoryService lhpDataVisibilityHistoryService;
    @Autowired
    private LhpDataRoadDetectorService lhpDataRoadDetectorService;
    @Autowired
    private LhpDataRoadDetectorHistoryService lhpDataRoadDetectorHistoryService;
    @Autowired
    private LhpDataWeatherStationService lhpDataWeatherStationService;
    @Autowired
    private LhpDataWeatherStationHistoryService lhpDataWeatherStationHistoryService;

    //刷新设备连接列表
    public void refreshDataCollectionMap(HashMap<String, DataCollection> map) {
        List<LhpInstallationPointEntity> pointList = this.list();
        List<LhpEquipmentEntity> equipmentList=lhpEquipmentService.list();
        for(LhpInstallationPointEntity point : pointList){
            //如果是串口服务器
            if(point.getNetworkDeviceType()==0){
                if(!map.containsKey(point.getNetworkDeviceIp())){
                    DataCollection dc= new DataCollection(point.getId(),point.getId(),point.getNetworkDeviceIp(),point.getNetworkDeviceIp());
                    map.put(dc.getSensorNo(), dc);
                }
                for (LhpEquipmentEntity equipment:equipmentList) {
                    if(point.getId().equals(equipment.getPointId())){
                        map.get(point.getNetworkDeviceIp()).getEquipmentMap().put(equipment.getId(),equipment);
                    }
                }
            }else if(point.getNetworkDeviceType()==1){//如果是DTU
                if(!map.containsKey(point.getPointCode())){
                    DataCollection dc= new DataCollection(point.getId(),point.getId(),point.getPointCode(),point.getPointCode());
                    map.put(dc.getSensorNo(), dc);
                }
                for (LhpEquipmentEntity equipment:equipmentList) {
                    if(point.getId().equals(equipment.getPointId())){
                        map.get(point.getPointCode()).getEquipmentMap().put(equipment.getEquipmentCode(),equipment);
                    }
                }
            }
        }
    }

    //存储采集的数据
    public void insertCollectionData(HashMap<String, DataCollection> map) {

        List<LhpThresholdSettingEntity> ltSettingYpts = lhpThresholdSettingService.list();
        List<LhpInstallationPointEntity> pointList =this.list();
        List<LhpEquipmentEntity> equipmentList = lhpEquipmentService.list();

        HashMap<String,LhpThresholdSettingEntity> settingMap = new HashMap<String,LhpThresholdSettingEntity>();
        HashMap<String, LhpEquipmentEntity> equipmentMap = new HashMap<String, LhpEquipmentEntity>();
        HashMap<String, LhpInstallationPointEntity> pointMap = new HashMap<String, LhpInstallationPointEntity>();

        for(LhpThresholdSettingEntity setting : ltSettingYpts){
            settingMap.put(setting.getEquimentId()+"-"+setting.getLevelId(), setting);
        }
        for (LhpEquipmentEntity equipment : equipmentList) {
            equipmentMap.put(equipment.getId(), equipment);
        }
        for (LhpInstallationPointEntity point : pointList) {
            pointMap.put(point.getId(), point);
        }

        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.add(calendar.MINUTE, -20);

        for (Map.Entry<String, DataCollection> entry : map.entrySet()) {
            DataCollection dc = entry.getValue();
            String pointCode = entry.getKey();
            System.out.println("安装点编码----------"+pointCode);

            LhpInstallationPointEntity point = pointMap.get(dc.getPointId());
            LhpDataVisibilityEntity dataVisibility = dc.getLhpDataVisibilityEntity();
            System.out.println("能见度对象---------"+dataVisibility);

            HashMap<String, String> hasDataMap = new HashMap<String, String>();
            boolean hasData = false;

            if (dataVisibility != null) {
                hasDataMap.put(dataVisibility.getEquipmentId(), dataVisibility.getEquipmentId());
                hasData = true;
                dataVisibility.setDataTime(date);
                dataVisibility.setWaysectId(point.getWaysectId());
                lhpDataVisibilityService.save(dataVisibility);
                LhpDataVisibilityHistoryEntity dataVisibilityHistory=new LhpDataVisibilityHistoryEntity();
                BeanUtils.copyProperties(dataVisibility, dataVisibilityHistory);
                lhpDataVisibilityHistoryService.save(dataVisibilityHistory);
                //存储报警
                for(int i = 1;i < 5;i++){
                    LhpThresholdSettingEntity setting = settingMap.get(dataVisibility.getEquipmentId()+"-"+i);
                    if(dataVisibility.getVisibility() != null){
                        String b = dataVisibility.getVisibility();
                        if(setting!= null && setting.getVisibilityStatus().equals("0")){
                            try{
                                ScriptEngineManager manager = new ScriptEngineManager();
                                ScriptEngine engine = manager.getEngineByName("js");
                                engine.put("X", b);
                                Object result = engine.eval(StringEscapeUtils.unescapeXml(setting.getVisibility()));
                                if((Boolean)result == true){
                                    LhpAlertEntity alert = new LhpAlertEntity();
                                    alert.setPointId(dataVisibility.getPointId());
                                    alert.setEquipmentId(dataVisibility.getEquipmentId());
                                    alert.setAlertTime(dataVisibility.getDataTime());
                                    alert.setAlertInfo("路面能见度为"+b+"米");
                                    alert.setAlertLevel(""+i);
                                    alert.setAlertStatus("1");
                                    alert.setAlertValue(b);
                                    alert.setWaysectId(point.getWaysectId());
                                    alert.setAlertType("visibility");
                                    lhpAlertService.save(alert);
                                    LhpAlertHistoryEntity alertHistory=new LhpAlertHistoryEntity();
                                    BeanUtils.copyProperties(alert,alertHistory);
                                    lhpAlertHistoryService.save(alertHistory);
                                }
                            }catch(Exception e){
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }

            LhpDataRoadDetectorEntity dataRoadDetector = dc.getLhpDataRoadDetectorEntity();
            System.out.println("地面探测器对象---------"+dataRoadDetector);
            if (dataRoadDetector != null) {
                hasDataMap.put(dataRoadDetector.getEquipmentId(), dataRoadDetector.getEquipmentId());
                hasData = true;
                dataRoadDetector.setId(null);
                dataRoadDetector.setDataTime(date);
                dataRoadDetector.setWaysectId(point.getWaysectId());
                lhpDataRoadDetectorService.save(dataRoadDetector);
                LhpDataRoadDetectorHistoryEntity dataRoadDetectorHistory=new LhpDataRoadDetectorHistoryEntity();
                BeanUtils.copyProperties(dataRoadDetector,dataRoadDetectorHistory);
                lhpDataRoadDetectorHistoryService.save(dataRoadDetectorHistory);
               //根据阈值存储报警
                Class dataRoadDetectorClass = dataRoadDetector.getClass();
                Field[] fields = dataRoadDetectorClass.getDeclaredFields();
                for(int i = 1;i < 5;i++){
                    LhpThresholdSettingEntity setting = settingMap.get(dataRoadDetector.getEquipmentId()+"-"+i);
                    if(setting != null){
                        Class ltsClass = setting.getClass();
                        for(Field field: fields){
                            try{
                                field.setAccessible(true);
                                String nameString = field.getName();
                                Object valueString = field.get(dataRoadDetector);
                                Field statusField = ltsClass.getDeclaredField(nameString+"Status");
                                Field valueField = ltsClass.getDeclaredField(nameString);
                                if(statusField != null){
                                    statusField.setAccessible(true);
                                    valueField.setAccessible(true);
                                    Object ltsStatusObject = statusField.get(setting);
                                    Object ltsValueObject = valueField.get(setting);
                                    if("0".equals(ltsStatusObject.toString())){
                                        if(valueString != null){
                                            try{
                                                ScriptEngineManager manager = new ScriptEngineManager();
                                                ScriptEngine engine = manager.getEngineByName("js");
                                                engine.put("X", valueString);
                                                Object result = engine.eval(ltsValueObject.toString());
                                                if((Boolean)result == true){
                                                    LhpAlertEntity alert = new LhpAlertEntity();
                                                    alert.setPointId(dataRoadDetector.getPointId());
                                                    alert.setEquipmentId(dataRoadDetector.getEquipmentId());
                                                    alert.setAlertTime(dataRoadDetector.getDataTime());
                                                    alert.setAlertInfo(this.getAlertInfo(nameString,valueString.toString()));
                                                    alert.setAlertLevel(i+"");
                                                    alert.setAlertStatus("1");
                                                    alert.setAlertValue(valueString.toString());
                                                    alert.setWaysectId(point.getWaysectId());
                                                    alert.setAlertType(nameString);
                                                    lhpAlertService.save(alert);
                                                    LhpAlertHistoryEntity alertHistory=new LhpAlertHistoryEntity();
                                                    BeanUtils.copyProperties(alert,alertHistory);
                                                    lhpAlertHistoryService.save(alertHistory);
                                                }
                                            }catch(Exception e){
                                                //e.printStackTrace();
                                            }
                                        }
                                    }
                                }
                            }
                            catch(Exception e){
                               // e.printStackTrace();
                            }
                        }
                    }
                }
            }

            //存储气象站数据
            LhpDataWeatherStationEntity dataWeatherStation = dc.getLhpDataWeatherStationEntity();
            if (dataWeatherStation != null) {
                hasDataMap.put(dataWeatherStation.getEquipmentId(), dataWeatherStation.getEquipmentId());
                hasData = true;
                dataWeatherStation.setId(null);
                dataWeatherStation.setDataTime(date);
                dataWeatherStation.setWaysectId(point.getWaysectId());
                lhpDataWeatherStationService.save(dataWeatherStation);
                LhpDataWeatherStationHistoryEntity ldwsh=new LhpDataWeatherStationHistoryEntity();
                BeanUtils.copyProperties(dataWeatherStation,ldwsh);
                lhpDataWeatherStationHistoryService.save(ldwsh);

                Class dataWeatherStationClass = dataWeatherStation.getClass();
                Field[] fields = dataWeatherStationClass.getDeclaredFields();
                for(int i = 1;i < 5;i++){
                    LhpThresholdSettingEntity setting = settingMap.get(dataWeatherStation.getEquipmentId()+"-"+i);
                    if(setting != null){
                        Class ltsClass = setting.getClass();
                        for(Field field: fields){
                            try{
                                field.setAccessible(true);
                                String nameString = field.getName();
                                Object valueString = field.get(dataWeatherStation);
                                Field statusField = ltsClass.getDeclaredField(nameString+"Status");
                                Field valueField = ltsClass.getDeclaredField(nameString);
                                if(statusField != null){
                                    statusField.setAccessible(true);
                                    valueField.setAccessible(true);
                                    Object ltsStatusObject = statusField.get(setting);
                                    Object ltsValueObject = valueField.get(setting);
                                    if(ltsStatusObject.toString().equals("0")){
                                        if(valueString != null){
                                            try{
                                                ScriptEngineManager manager = new ScriptEngineManager();
                                                ScriptEngine engine = manager.getEngineByName("js");
                                                engine.put("X", valueString);
                                                Object result = engine.eval(ltsValueObject.toString());
                                                if((Boolean)result == true){
                                                    LhpAlertEntity la = new LhpAlertEntity();
                                                    la.setPointId(dataWeatherStation.getPointId());
                                                    la.setEquipmentId(dataWeatherStation.getEquipmentId());
                                                    la.setAlertTime(dataWeatherStation.getDataTime());
                                                    la.setAlertInfo(getAlertInfo(nameString,valueString.toString()));
                                                    la.setAlertLevel(""+i);
                                                    la.setAlertStatus("1");
                                                    la.setAlertValue(valueString.toString());
                                                    la.setWaysectId(point.getWaysectId());
                                                    la.setAlertType(nameString);
                                                    lhpAlertService.save(la);
                                                    LhpAlertHistoryEntity lah=new LhpAlertHistoryEntity();
                                                    BeanUtils.copyProperties(la,lah);
                                                    lhpAlertHistoryService.save(lah);
                                                }
                                            }catch(Exception e){
                                               // e.printStackTrace();
                                            }
                                        }
                                    }
                                }
                            }
                            catch(Exception e){
                                //e.printStackTrace();
                            }
                        }
                    }
                }
            }
            //判断设备是否在线  20分钟没上数据视为离线
            Map<String,LhpEquipmentEntity> aaa=  dc.getEquipmentMap();
            for(String key : aaa.keySet()) {
                LhpEquipmentEntity equipment = (LhpEquipmentEntity) dc.getEquipmentMap().get(key);
                if(!hasDataMap.containsKey(equipment.getId())){
                    LhpEquipmentEntity le = equipmentMap.get(equipment.getId());
                    if(le != null){
                        if(le.getEquipmentType()==2){
                            List<LhpDataWeatherStationEntity> wlist=lhpDataWeatherStationService.list(
                                    new QueryWrapper<LhpDataWeatherStationEntity>()
                                    .eq(StringUtils.isNotBlank(le.getId()),"equipment_id", le.getId())
                                    .ge(StringUtils.isNotBlank(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime())),"data_time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()))
                            );
                            if(wlist.size()>0) {
                                le.setEquipmentStatus(0);
                                System.err.println("----气象站查询到有数据-----设备设置在线-----"+wlist.size());
                            }else {
                                le.setEquipmentStatus(1);
                                System.err.println("----气象站查询到无数据-----设备设置离线-----");
                            }
                            lhpEquipmentService.updateById(le);
                        }else if(le.getEquipmentType()==1){
                            List<LhpDataVisibilityEntity> vlist=lhpDataVisibilityService.list(
                                    new QueryWrapper<LhpDataVisibilityEntity>()
                                            .eq(StringUtils.isNotBlank(le.getId()),"equipment_id", le.getId())
                                            .ge(StringUtils.isNotBlank(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime())),"data_time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()))
                            );
                            if(vlist.size()>0) {
                                System.err.println("----能见度查询到有数据-----设备设置在线-----"+vlist.size());
                                le.setEquipmentStatus(0);
                            }else{
                                System.err.println("----能见度查询到无数据-----设备设置离线-----");
                                le.setEquipmentStatus(1);
                            }
                            lhpEquipmentService.updateById(le);
                        }else if(le.getEquipmentType()==3 || le.getEquipmentType()==0){
                            List<LhpDataRoadDetectorEntity> rlist=lhpDataRoadDetectorService.list(
                                    new QueryWrapper<LhpDataRoadDetectorEntity>()
                                            .eq(StringUtils.isNotBlank(le.getId()),"equipment_id", le.getId())
                                            .ge(StringUtils.isNotBlank(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime())),"data_time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()))
                            );
                            if(rlist.size()>0) {
                                System.err.println("----路面探测器查询到有数据-----设备设置在线-----" +rlist.size());
                                le.setEquipmentStatus(0);
                            }else{
                                System.err.println("----路面探测器查询到无数据-----设备设置离线-----");
                                le.setEquipmentStatus(1);
                            }
                            lhpEquipmentService.updateById(le);
                        }

                    }
                }else {
                    equipment.setEquipmentStatus(0);
                    System.err.println("----设备设置有数据直接在线-----"+equipment.getEquipmentName());
                    lhpEquipmentService.updateById(equipment);
                }

            }
            dc.setLhpDataRoadDetectorEntity(null);
            dc.setLhpDataVisibilityEntity(null);
            dc.setLhpDataWeatherStationEntity(null);
        }

    }

    @Override
    public List<BaseTree> pointTree() {
        List<LhpInstallationPointEntity> pointList=this.list();
        List<BaseTree> treeList=new ArrayList<>();

        for (LhpInstallationPointEntity pointEntity:pointList){
            BaseTree tree=new BaseTree();
            tree.setId(pointEntity.getId());
            tree.setParentId(pointEntity.getWaysectId());
            tree.setName(pointEntity.getPointName());
            treeList.add(tree);
        }
        return treeList;
    }


    //风速转换
    public static String getFldj(double fs) {

        String str = "";

        if(fs >= 0.0 && fs <= 0.2) {

            return "(0级)";
        }else if(fs >= 0.3 && fs <= 1.5) {

            return "(1级)";
        }else if(fs >= 1.6 && fs <= 3.3) {

            return "(2级)";
        }else if(fs >= 3.4 && fs <= 5.4) {

            return "(3级)";
        }else if(fs >= 5.5 && fs <= 7.9) {

            return "(4级)";
        }else if(fs >= 8.0 && fs <= 10.7) {

            return "(5级)";
        }else if(fs >= 10.8 && fs <= 13.8) {

            return "(6级)";
        }else if(fs >= 13.9 && fs <= 17.1) {

            return "(7级)";
        }else if(fs >= 17.2 && fs <= 20.7) {

            return "(8级)";
        }else if(fs >= 20.8 && fs <= 24.4) {

            return "(9级)";
        }else if(fs >= 24.5 && fs <= 28.4) {

            return "(10级)";
        }else if(fs >= 28.5 && fs <= 32.6) {

            return "(11级)";
        }else if(fs >= 32.7 && fs <= 36.9) {

            return "(12级)";
        }

        return str;

    }
    //组织报警信息
    public String getAlertInfo(String alertName,String alertValue){

        String str = "";

        switch(alertName){

            case "visibility":
                str = "能见度为"+alertValue+"米";
                break;
            case "copperProbeTemp":
                str = "铜探头温度"+alertValue+"℃";
                break;
            case "roadSurfaceTemp":
                str = "路面温度"+alertValue+"℃";
                break;
            case "freezingTemp":
                str = "冰点温度"+alertValue+"℃";
                break;
            case "salineConcentrationNaCl":
                str = "含盐量NaCl"+alertValue+"%";
                break;
            case "salineConcentrationCaCl":
                str = "含盐量CaCl"+alertValue+"%";
                break;
            case "salineConcentrationMgCl":
                str = "含盐量MgCl"+alertValue+"%";
                break;
            case "icePossible":
                str = "结冰可能性"+alertValue+"%";
                break;
            case "externalTemp5cm":
                str = "路基温度（5cm深）"+alertValue+"℃";
                break;
            case "externalTemp30cm":
                str = "路基温度（30cm深）"+alertValue+"℃";
                break;
            case "freezingTempNaCl":
                str = "冰点温度NaCl"+alertValue+"℃";
                break;
            case "freezingTempMgCl":
                str = "冰点温度MgCl"+alertValue+"℃";
                break;
            case "freezingTempCaCl":
                str = "冰点温度CaCl"+alertValue+"℃";
                break;
            case "waterFilmHeight":
                str = "水膜高度"+alertValue+"μm";
                break;
            case "friction":
                str = "摩擦系数"+alertValue;
                break;
            case "roadCondition":
                str = "路面状况是"+alertValue;
                break;
            case "icePercentage":
                str = "含冰比例"+alertValue+"%";
                break;
            case "ambientTemp":
                str = "空气温度"+alertValue+"℃";
                break;
            case "relativeHumidity":
                str = "相对湿度"+alertValue+"%";
                break;
            case "dewPointTemp":
                str = "露点温度"+alertValue+"℃";
                break;
            case "relativeHumidityAtRoadTemp":
                str = "路面温度的相对湿度"+alertValue+"%";
                break;
            case "waterFilmHeightOnSmoothSurface":
                str = "平滑表面的水膜高度"+alertValue+"μm";
                break;
            case "windChillTemp":
                str = "风寒温度"+alertValue+"℃";
                break;
            case "wetBulbTemp":
                str = "湿球温度"+alertValue+"℃";
                break;
            case "specificEnthalpy":
                str = "比焓"+alertValue;
                break;
            case "pressure":
                str = "大气压强"+alertValue;
                break;
            case "windSpeed":
                str = "风速"+alertValue+"m/s("+getFldj(Double.parseDouble(alertValue))+")";
                break;
            case "windDirection":
                str = "风向"+alertValue+"度";
                break;
            case "precipitationType":
                str = "降水类型为"+alertValue;
                break;
            case "precipitationIntensity":
                str = "降水强度"+alertValue+"mm/h";
                break;
            default:
                break;
        }
        return str;
    }

}
